package any.incubator;

import static any.impl.util.MapEntry.createMapEntry;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Map.Entry;

import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import any.Any;
import any.AnyVisitor;
import any.SequentialAny;
import any.impl.util.Utils;
import ch.netcetera.wake.core.format.csv.CSVParser;

public class CSVAny extends BaseSequentialAny {

	private final Reader reader;

	public CSVAny(String s) {
		reader = new StringReader(s);
	}

	public CSVAny(File file) throws FileNotFoundException {
		reader = new FileReader(file);
	}
	
	@Override
	public boolean accept(AnyVisitor<SequentialAny> visitor) throws NullPointerException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Iterable<? extends Entry<String, ? extends SequentialAny>> entries() {
		return Utils.wrapIterator(new EntriesIterator(getParser()));
	}

	@Override
	public Iterable<? extends SequentialAny> iterable() {
		return Utils.wrapIterator(new AnyIterator(getParser()));
	}

	@Override
	public Any toAny(boolean mutable) throws UnsupportedOperationException {
		return Any.create.any(mutable, iterable());
	}
	
	@SuppressWarnings("synthetic-access")
	private abstract class BaseIterator {
		private CSVParser parser;
		BaseIterator(CSVParser parser) {
			this.parser = parser;
		}
		public boolean hasNext() {
			parser.getLine();
		}
		protected Any nextAny() throws NoSuchElementException {
			try {
				Object[] line = parser.getLine();
				if (line == null)  {
					throw new NoSuchElementException();
				}
				
				return Any.create.any(line);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			
		}
		public void remove() throws UnsupportedOperationException {
			throw new NotImplementedException();
		}
	}
	
	@SuppressWarnings("synthetic-access")
	private final class AnyIterator extends BaseIterator implements Iterator<Any> {
		AnyIterator(CSVParser parser) {
			super(parser);
		}

		public Any next() throws NoSuchElementException {
			return nextAny();
		}
	}
	
	@SuppressWarnings("synthetic-access")
	private final class EntriesIterator extends BaseIterator implements Iterator<Entry<String, ? extends SequentialAny>> {
		EntriesIterator(CSVParser parser) {
			super(parser);
		}

		public Entry<String, ? extends SequentialAny> next() throws NoSuchElementException {
			return createMapEntry(null, nextAny());
		}
	}
	
	private CSVParser getParser() {
		return new CSVParser(reader);
	}
	

}
